#include "aodv.h"
#include "aodv_types.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>

// 函数声明
void route_table_invalidate_via_neighbor(uint32_t neighbor_ip);

// 路由表最大条目数
#define MAX_ROUTE_ENTRIES 100

// 路由表全局变量
static route_table_entry_t route_table[MAX_ROUTE_ENTRIES];
static int route_table_count = 0;

// 添加路由表项
int route_table_add(route_table_entry_t *entry) {
    // 检查路由表是否已满
    if (route_table_count >= MAX_ROUTE_ENTRIES) {
        printf("Route table is full\n");
        return -1;
    }
    
    // 检查是否已存在相同目标的路由
    for (int i = 0; i < route_table_count; i++) {
        if (route_table[i].destination_ip == entry->destination_ip) {
            // 已存在，更新路由表项
            return route_table_update(entry);
        }
    }
    
    // 添加新路由表项
    memcpy(&route_table[route_table_count], entry, sizeof(route_table_entry_t));
    route_table_count++;
    
    printf("Added route: destination=%d.%d.%d.%d, next_hop=%d.%d.%d.%d, hop_count=%d\n",
           (entry->destination_ip >> 24) & 0xFF, (entry->destination_ip >> 16) & 0xFF, 
           (entry->destination_ip >> 8) & 0xFF, entry->destination_ip & 0xFF,
           (entry->next_hop_ip >> 24) & 0xFF, (entry->next_hop_ip >> 16) & 0xFF, 
           (entry->next_hop_ip >> 8) & 0xFF, entry->next_hop_ip & 0xFF,
           entry->hop_count);
    
    return 0;
}

// 更新路由表项
int route_table_update(route_table_entry_t *entry) {
    for (int i = 0; i < route_table_count; i++) {
        if (route_table[i].destination_ip == entry->destination_ip) {
            // 路由更新策略：仅当收到更新的路由信息时更新路由
            // 1. 如果目标序列号更大，更新路由
            // 2. 如果目标序列号相同但跳数更小，更新路由
            if (entry->destination_seq_num > route_table[i].destination_seq_num ||
                (entry->destination_seq_num == route_table[i].destination_seq_num && 
                 entry->hop_count < route_table[i].hop_count)) {
                
                memcpy(&route_table[i], entry, sizeof(route_table_entry_t));
                
                printf("Updated route: destination=%d.%d.%d.%d, next_hop=%d.%d.%d.%d, hop_count=%d\n",
                       (entry->destination_ip >> 24) & 0xFF, (entry->destination_ip >> 16) & 0xFF, 
                       (entry->destination_ip >> 8) & 0xFF, entry->destination_ip & 0xFF,
                       (entry->next_hop_ip >> 24) & 0xFF, (entry->next_hop_ip >> 16) & 0xFF, 
                       (entry->next_hop_ip >> 8) & 0xFF, entry->next_hop_ip & 0xFF,
                       entry->hop_count);
                
                return 0;
            } else {
                printf("Route update not needed: destination=%d.%d.%d.%d\n",
                       (entry->destination_ip >> 24) & 0xFF, (entry->destination_ip >> 16) & 0xFF, 
                       (entry->destination_ip >> 8) & 0xFF, entry->destination_ip & 0xFF);
                return 1; // 不需要更新
            }
        }
    }
    
    // 路由不存在，添加新路由
    return route_table_add(entry);
}

// 查找路由表项
route_table_entry_t *route_table_find(uint32_t dest_ip) {
    for (int i = 0; i < route_table_count; i++) {
        if (route_table[i].destination_ip == dest_ip) {
            // 检查路由是否有效
            if (route_table[i].route_flags & ROUTE_FLAG_VALID) {
                return &route_table[i];
            }
            break;
        }
    }
    return NULL;
}

// 删除路由表项
int route_table_delete(uint32_t dest_ip) {
    for (int i = 0; i < route_table_count; i++) {
        if (route_table[i].destination_ip == dest_ip) {
            // 从路由表中删除，将最后一个条目移到当前位置
            if (i < route_table_count - 1) {
                memcpy(&route_table[i], &route_table[route_table_count - 1], sizeof(route_table_entry_t));
            }
            route_table_count--;
            
            printf("Deleted route: destination=%d.%d.%d.%d\n",
                   (dest_ip >> 24) & 0xFF, (dest_ip >> 16) & 0xFF, 
                   (dest_ip >> 8) & 0xFF, dest_ip & 0xFF);
            
            return 0;
        }
    }
    return -1; // 未找到路由
}

// 使路由表项无效
void route_table_invalidate(uint32_t dest_ip) {
    route_table_entry_t *entry = route_table_find(dest_ip);
    if (entry != NULL) {
        entry->route_flags &= ~ROUTE_FLAG_VALID;
        entry->route_flags |= ROUTE_FLAG_INVALID;
        entry->route_type = ROUTE_TYPE_INVALID;
        
        printf("Invalidated route: destination=%d.%d.%d.%d\n",
               (dest_ip >> 24) & 0xFF, (dest_ip >> 16) & 0xFF, 
               (dest_ip >> 8) & 0xFF, dest_ip & 0xFF);
    }
}

// 使通过指定下一跳的所有路由无效
void route_table_invalidate_via_neighbor(uint32_t neighbor_ip) {
    printf("Invalidating all routes via neighbor: %d.%d.%d.%d\n",
           (neighbor_ip >> 24) & 0xFF, (neighbor_ip >> 16) & 0xFF, 
           (neighbor_ip >> 8) & 0xFF, neighbor_ip & 0xFF);
    
    for (int i = 0; i < route_table_count; i++) {
        if (route_table[i].next_hop_ip == neighbor_ip) {
            route_table[i].route_flags &= ~ROUTE_FLAG_VALID;
            route_table[i].route_flags |= ROUTE_FLAG_INVALID;
            route_table[i].route_type = ROUTE_TYPE_INVALID;
            
            printf("Route to %d.%d.%d.%d via %d.%d.%d.%d invalidated due to link failure\n",
                   (route_table[i].destination_ip >> 24) & 0xFF, 
                   (route_table[i].destination_ip >> 16) & 0xFF, 
                   (route_table[i].destination_ip >> 8) & 0xFF, 
                   route_table[i].destination_ip & 0xFF,
                   (neighbor_ip >> 24) & 0xFF, 
                   (neighbor_ip >> 16) & 0xFF, 
                   (neighbor_ip >> 8) & 0xFF, 
                   neighbor_ip & 0xFF);
        }
    }
}

// 打印路由表
void aodv_print_route_table(void) {
    printf("\n=== Route Table (%d entries) ===\n", route_table_count);
    printf("%-15s %-15s %-10s %-8s %-10s %-15s\n",
           "Destination", "Next Hop", "Seq Num", "Hops", "Flags", "Expiration");
    
    for (int i = 0; i < route_table_count; i++) {
        route_table_entry_t *entry = &route_table[i];
        char flags_str[16] = {0};
        int flag_idx = 0;
        
        if (entry->route_flags & ROUTE_FLAG_VALID) flags_str[flag_idx++] = 'V';
        if (entry->route_flags & ROUTE_FLAG_REPAIR) flags_str[flag_idx++] = 'R';
        if (entry->route_flags & ROUTE_FLAG_ERROR) flags_str[flag_idx++] = 'E';
        if (entry->route_flags & ROUTE_FLAG_INVALID) flags_str[flag_idx++] = 'I';
        
        printf("%d.%d.%d.%d  %d.%d.%d.%d  %-10u %-8u %-10s %u\n",
               (entry->destination_ip >> 24) & 0xFF, 
               (entry->destination_ip >> 16) & 0xFF, 
               (entry->destination_ip >> 8) & 0xFF, 
               entry->destination_ip & 0xFF,
               (entry->next_hop_ip >> 24) & 0xFF, 
               (entry->next_hop_ip >> 16) & 0xFF, 
               (entry->next_hop_ip >> 8) & 0xFF, 
               entry->next_hop_ip & 0xFF,
               entry->destination_seq_num,
               entry->hop_count,
               flags_str,
               entry->expiration_time);
    }
    printf("=============================\n\n");
}